﻿/*****************************************************************//**
 * @file    FITKAcousticsVTKGraphObjectSEASubSystem.h
 * @brief   Graph object base for sub-system data.
 *  
 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-11-04
 *********************************************************************/

#ifndef __FITKACOUSTICSVTKGRAPHOBJECTSEASUBSYSTEM_H__
#define __FITKACOUSTICSVTKGRAPHOBJECTSEASUBSYSTEM_H__

#include "FITKAcousticsVTKGraphObject3DPost.h"

#include "FITKAcousticsVTKGraphAdaptorAPI.h"

// Forward declaration
class vtkUnstructuredGrid;
class vtkPoints;

class FITKAcousticsVTKGraphActor;

namespace Acoustics
{
    class FITKAbstractSEASubSys;
    class FITKAcousticsDiscNodeList;
}

namespace Exchange
{
    class FITKAcousticsVTKGraphObjectSelect;
}

namespace Exchange
{
    /**
     * @brief   Graph object base for 'sub-system'.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-11-04
     */
    class FITKACOUSTICSGRAPHADAPTORAPI FITKAcousticsVTKGraphObjectSEASubSystem : public FITKAcousticsVTKGraphObject3DPost
    {
        // Regist
        FITKGraphObjectRegist(FITKAcousticsVTKGraphObjectSEASubSystem, FITKAcousticsVTKGraphObject3DPost);
        FITKCLASS(Exchange, FITKAcousticsVTKGraphObjectSEASubSystem);

    public:
        /**
         * @brief   Constructor.
         * @param   subSys: The sub-system data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        FITKAcousticsVTKGraphObjectSEASubSystem(Acoustics::FITKAbstractSEASubSys* subSys);

        /**
         * @brief   Destructor.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual ~FITKAcousticsVTKGraphObjectSEASubSystem();

        /**
         * @brief   Update all graph actors.[virtual][override]
         * @param   forceUpdate: Force update[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void update(bool forceUpdate = false) override;

        /**
         * @brief   Highlight the graph actors.[virtual][override]
         * @param   type: The shape type need to be highlighted[default]
         * @param   color: The given color for highlighting this time[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void highlight(FITKAcousticsVTKCommons::ShapeType type = FITKAcousticsVTKCommons::ShapeTypeNone, QColor color = QColor()) override;

        /**
         * @brief   Dis-highlight the graph actors.[virtual][override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void disHighlight() override;

        /**
         * @brief   Advanced highlight mode for highlighting part of the graph actors.[virtual][override]
         * @param   type: The type of the model need to be highlighted
         * @param   indice: The given indice of the model component need to be highlight
         * @param   color: The given color for highlighting this time[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void advanceHighlight(FITKAcousticsVTKCommons::ShapeType type, QVector<int> indice, QColor color = QColor()) override;

        /**
         * @brief   Dis-highlight the graph actors if the graph object is in advanced highlighting mode.[virtual][override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void disAdvanceHighlight() override;

        /**
         * @brief   Set if the graph object pickable mode.[virtual][override]
         * @param   mode: The pickable mode
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void setPickMode(FITKAcousticsVTKCommons::ShapePickMode mode) override;

        /**
         * @brief   Enable or disable the scale mode.[virtual]
         * @param   isOn: Is the mode enabled
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        virtual void setEnableScale(bool isOn);

        /**
         * @brief   Save the post data dict.[virtual][override]
         * @param   arrayName: The array name of the post data
         * @param   data: The post data
         *          The key is the data object name.
         *          The value is the post value.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        virtual void setPostData(QString arrayName, QHash<QString, float> & data) override;

        /**
         * @brief   Update the color by the data color array in cell data.[virtual][override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        virtual void updateByDataColor() override;

        /**
         * @brief   Update the color by the post data for cell data.[virtual][override]
         * @param   arrayName: The data array name
         * @param   rangeMin: The min range for the look up table
         * @param   rangeMax: The max range for the look up table
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        virtual void updateByPostCellData(QString arrayName, double rangeMin, double rangeMax) override;

        /**
         * @brief   Update the color by the NULL post data for cell data.[virtual][override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        virtual void updateByPostNullData() override;

        /**
         * @brief   Enable or disbale log scale mode.[virtual][override]
         * @param   isOn: Enable or disable
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-28
         */
        virtual void setEnableLogScale(bool isOn) override;

        /**
         * @brief   Get the visibility from the data object.[virtual][override]
         * @return  The visibility
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-29
         */
        virtual bool getDataVisibility() override;

    protected:
        /**
         * @brief   Intialize.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void init();

        /**
         * @brief   Generate the vtkPoints for the sub-system with the SEA nodes.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void generateSEANodes();

        /**
         * @brief   Generate the scaled vtkPoints for the sub-system with the given scaled center.[virtual]
         * @param   center: The scaled center
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        virtual void generateScaledSEANodes(double* center);

        /**
         * @brief   Generate the vtkDataSet for the sub-system.[pure virtual]
         * @param   subSys: The sub-system data
         * @return  Is the data valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual bool generateDataSet(Acoustics::FITKAbstractSEASubSys* subSys) = 0;

        /**
         * @brief   Generate the actor with the sub-system data.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        virtual void generateGraph();

        /**
         * @brief   Get the SEA node list from the data object.
         * @return  The SEA nodes data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        Acoustics::FITKAcousticsDiscNodeList* getSEANodesData();

        /**
         * @brief   Get the VTK mesh grid by the given mesh type.[override]
         * @param   type: The shape's VTK mesh type
         * @return  The vtkDataSet object of the given type of mesh
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        vtkDataSet* getMesh(FITKAcousticsVTKCommons::ShapeType type) override;

        /**
         * @brief   Get the scale factor of the sub system.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        virtual double getScaleFactor();

        /**
         * @brief   Get the visibility of SEA sub-system with runtime settings.
         * @return  The visibility
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-14
         */
        bool getGlobalSEASubSystemVisibility();

        /**
         * @brief   Clear all vtk data.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-14
         */
        virtual void resetVtkData();

    protected:
        /**
         * @brief   The grid data for the sub-system.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        vtkUnstructuredGrid* m_ugrid{ nullptr };

        /**
         * @brief   The points of the SEA nodes.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        vtkPoints* m_points{ nullptr };

        /**
         * @brief   The points of the scaled SEA nodes.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        vtkPoints* m_pointsScaled{ nullptr };

        /**
         * @brief   The actor for the sub-system grid.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        FITKAcousticsVTKGraphActor* m_fActor{ nullptr };

        /**
         * @brief   The model extractor for normal or advanced highlight.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-04
         */
        FITKAcousticsVTKGraphObjectSelect* m_highlightSelector{ nullptr };

        /**
         * @brief   The dict for SEA nodes id and VTK points index.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        QHash<int, int> m_nodeIdPointIndexHash;

        /**
         * @brief   Enable flag for scale mode.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-12
         */
        bool m_enableScale = false;

        /**
         * @brief   Wether the graph object has at least one valid value for the post.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        bool m_hasValidPostData = false;

    };
}   // namespace Exchange

#endif // __FITKACOUSTICSVTKGRAPHOBJECTSEASUBSYSTEM_H__
